#!/usr/bin/env python
# -*- coding: utf-8 -*-

from sanic.response import json
import opentracing

from sanic.handlers import ErrorHandler
from opentracing.ext import tags
from core.exception import CustomException

from cryptography.fernet import Fernet
from sanic.request import json_loads
from sanic.response import json_dumps
from . import logger
import traceback
PAGE_COUNT = 20

def jsonify(records):
    return [dict(r.items()) for r in records]

class CustomHandler(ErrorHandler):

    def default(self, request, exception):
        logger.error(traceback.format_exc())
        if isinstance(exception, CustomException):
            data = {
                'message': exception.message,
                'code': exception.code,
            }
            if exception.error:
                data.update({'error': exception.error})
            return json(data, status=exception.status_code)
        else:

            return json({'code':400,'info':'系统错误','error':'系统错误'})


def before_request(request):
    try:
        span_context = opentracing.tracer.extract(
            format=opentracing.Format.HTTP_HEADERS,
            carrier=request.headers
        )
    except Exception as e:
        span_context = None
    handler = request.app.router.get(request)
    span = opentracing.tracer.start_span(operation_name=handler[0].__name__,
                             child_of=span_context)
    span.log_kv({'event': 'server'})
    span.set_tag('http.url', request.url)
    span.set_tag('http.method', request.method)
    ip = request.ip
    if ip:
        span.set_tag(tags.PEER_HOST_IPV4, "{}:{}".format(ip[0], ip[1]))
    return span

def create_span(span_id, parent_span_id, trace_id, span_name,
                start_time, duration, annotations,
                binary_annotations):
    span_dict = {
        'traceId': trace_id,
        'name': span_name,
        'id': span_id,
        'parentId': parent_span_id,
        'timestamp': start_time,
        'duration': duration,
        'annotations': annotations,
        'binaryAnnotations': binary_annotations
    }
    return span_dict




def set_auth_cookies(token,cookies):
    '''
    加密cookies
    :param token:
    :param cookies:
    :return:
    '''
    f = Fernet(token)
    cookies_json = json_dumps(cookies)
    token = f.encrypt(cookies_json.encode())
    cookies_json = token.decode()
    return cookies_json

def get_auth_cookies(token, cookies):
    '''
    解密cookies
    :param token:
    :param cookies:
    :return:
    '''
    if isinstance(token,bytes):
        token = token.decode('utf-8')
    f = Fernet(token)
    cookie_json = f.decrypt(cookies.encode()).decode()
    cookies_data = json_loads(cookie_json)
    return cookies_data

